package com.grancalavera.flixel.spaceinvaders
{
import org.flixel.*;
/**
 * Main game state
 */
public class PlayState extends FlxState
{

    //--------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Creates a new instance of this class.
     */
    public function PlayState()
    {
        Sounds;
        FlxG.mouse.hide();
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
 
    //----------------------------------
    //  weapon
    //----------------------------------
    /**
     *  @private
     */
    private var weapon:Class = Bullet;
 
    //----------------------------------
    //  gameOver
    //----------------------------------
    /**
     *  @private
     */
    private var gameOver:Boolean;

    //----------------------------------
    //  bullets
    //----------------------------------
    /**
     *  @private
     */
    public var bullets:FlxGroup;

    //----------------------------------
    //  invaderBullets
    //----------------------------------
    /**
     *  @private
     */
    private var invaderBullets:FlxGroup;
 
    //----------------------------------
    //  boundaries
    //----------------------------------
    /**
     *  @private
     */
    private var boundaries:FlxGroup;
    
    //----------------------------------
    //  barriers
    //----------------------------------
    /**
     *  @private
     */
    private var barriers:FlxGroup;
    
    //----------------------------------
    //  cannon
    //----------------------------------
    /**
     *  @private
     */
    private var cannon:Cannon;

    //----------------------------------
    //  wave
    //----------------------------------
    /**
     *  @private
     */
    private var wave:Wave;

    //----------------------------------
    //  maxLivingBullets
    //----------------------------------
    /**
     *  @private
     */
    private var maxLivingBullets:int = 1;

    //----------------------------------
    //  maxLivingInvaderBullets
    //----------------------------------
    /**
     *  @private
     */
    private var maxLivingInvaderBullets:int = 2;

    //----------------------------------
    //  invaderFireFrequency
    //----------------------------------
    /**
     *  @private
     */
    private var invaderFireFrequency:Number = 0.5;

    //----------------------------------
    //  elapsedSinceLastInvaderFire
    //----------------------------------
    /**
     *  @private
     */
    private var elapsedSinceLastInvaderFire:Number = invaderFireFrequency;

    //----------------------------------
    //  waveFireFrequency
    //----------------------------------
    /**
     *  @private
     */
    private var waveFireFrequency:Number = 2;

    //----------------------------------
    //  elapsedSinceLastWaveFire
    //----------------------------------
    /**
     *  @private
     */
    private var elapsedSinceLastWaveFire:Number = waveFireFrequency;

    //--------------------------------------------------------------------------
    //
    //  Overridden Methods - FlxState
    //
    //--------------------------------------------------------------------------    
    
	override public function create():void
	{
        bullets = new FlxGroup();
        add(bullets);
        
        invaderBullets = new FlxGroup();
        add(invaderBullets);
        
        cannon = new Cannon();
        cannon.x = FlxG.width/2 - cannon.width / 2;
        cannon.y = FlxG.height - cannon.height;
        add(cannon);
        
        wave = new Wave();
        wave.y = 0;
        wave.x = FlxG.width / 2 - wave.defaultWidth / 2;
        add(wave);
        
        boundaries = new FlxGroup();
        add(boundaries);
        boundaries.add(new Boundary());
        boundaries.add(new Boundary(FlxG.width - 50));
        
        
        var barrierY:Number = FlxG.height - Barrier.HEIGHT * 2;
        barriers = new FlxGroup();
        barriers.y = barrierY;
        
        barriers.add(new Barrier(
            FlxG.width / 4 - Barrier.WIDTH / 2));
        barriers.add(new Barrier(
            FlxG.width / 2 - Barrier.WIDTH / 2));
        barriers.add(new Barrier(
            FlxG.width / 4 * 3 - Barrier.WIDTH / 2));
            
        add(barriers);
	}
    
    override public function update():void
    {
        if (gameOver)
        {
            FlxG.mouse.show();
            if (FlxG.mouse.justPressed())
                FlxG.state = new PlayState();
                        
            return;
        }
            
        if (cannon.dead || wave.countLiving() == 0)
        {
            gameOver = true;
            add(new SplashText());        
        }
        
        FlxU.overlap(wave, boundaries, overlapWaveBoundaries);
        FlxU.overlap(wave, bullets, overlapWaveBullet);
        FlxU.overlap(bullets, barriers, overlapBulletBarrier);
        FlxU.overlap(invaderBullets, barriers, overlapBulletBarrier);
        FlxU.overlap(invaderBullets, cannon, overlapInvaderBulletsCannon);
        
        if (FlxG.keys.pressed("SPACE"))
            fireCannon();
        
        if (FlxG.keys.justPressed("ONE"))
        {
            maxLivingBullets = 1;
            weapon = Bullet;
        }

        if (FlxG.keys.justPressed("TWO"))
        {
            maxLivingBullets = 10;
            weapon = Bullet;
        }        
        
        if (FlxG.keys.justPressed("THREE"))
        {
            maxLivingBullets = 1;
            weapon = ClusterBomb;
        }

        super.update();

        if (
            elapsedSinceLastWaveFire > waveFireFrequency && 
            !cannon.dead &&
            wave.countLiving() > 0
        )
        {
            if (elapsedSinceLastInvaderFire > invaderFireFrequency)
            {
                fireInvader();
                elapsedSinceLastInvaderFire = 0;
                
                if (invaderBullets.countLiving() > 1)
                    elapsedSinceLastWaveFire = 0;
            }
            elapsedSinceLastInvaderFire += FlxG.elapsed;
        }
        
        elapsedSinceLastWaveFire += FlxG.elapsed;
    }


    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------    

    /**
     *  @private
     */
    private function fireCannon():void
    {
        if (bullets.countLiving() < maxLivingBullets)
        {
            bullets.add(new weapon(cannon.x + cannon.width / 2, FlxG.height - 20));
            FlxG.play(Sounds.CANNON);        
        }
    }

    //----------------------------------
    //  fireAlien
    //----------------------------------
    /**
     * @private
     */
    private function fireInvader():void
    {
        var invader:FlxSprite = wave.getFiringInvader();
        invaderBullets.add(
            new Bullet(
                (invader.x + (invader.width / 2)), 
                (invader.y + invader.height), 
                Bullet.INVADER
            )
        );
        FlxG.play(Sounds.INVADER);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overlap Callbacks
    //
    //--------------------------------------------------------------------------    

    //----------------------------------
    //  overlapWaveBoundaries
    //----------------------------------    
    /**
     *  @private
     */
    private function overlapWaveBoundaries(invader:FlxSprite, boudary:FlxSprite):void
    {
        wave.advance();
    }

    //----------------------------------
    //  overlapWaveBullet
    //----------------------------------    
    /**
     *  @private
     */
    private function overlapWaveBullet(invader:FlxSprite, bullet:FlxSprite):void
    {
        invader.kill();
        bullet.kill();
    }

    //----------------------------------
    //  overlapBulletBarrier
    //----------------------------------    
    /**
     *  @private
     */
    private function overlapBulletBarrier(bullet:FlxSprite, barrierBlock:FlxSprite):void
    {
        bullet.kill();
        barrierBlock.kill();
    }

    //----------------------------------
    //  overlapInvaderBulletsCannon
    //----------------------------------
    /**
     * @private
     */
    private function overlapInvaderBulletsCannon(bullet:FlxSprite, cannon:FlxSprite):void
    {
        this.cannon.kill();
        bullet.kill();
    }

}
}
